Estoy tratando de hacer coincidir el funcionamiento de la función de resolve de una promesa con el procedimiento correspondiente en la especificación ECMAScript. Más específicamente, estoy buscando la especificación en el caso de que se llame a la función de resolución con un valor de objeto.
Toma estos ejemplos:
new Promise((resolve) => { resolve("hello"); }); new Promise((resolve) => { resolve({a: 100}); }); Hay una diferencia entre estas dos promesas: el tipo de valor pasado a la función de resolve .
Este es el procedimiento para la función de resolución de la especificación ECMAScript :
Sea F el objeto de la función activa.
Afirmar: F tiene una [[Promesa]] ranura interna cuyo valor es un Objeto.
Sea promesa F .[[Promesa]].
Sea yaResuelto F .[[YaResuelto]].
Si yaResuelto .[[Valor]] es verdadero , devuelve undefined .
Establezca yaResuelto .[[Valor]] en verdadero .
Si SameValue( resolución , promesa ) es verdadero , entonces
una. Deje que selfResolutionError sea un objeto TypeError recién creado.
b. Devuelve RejectPromise( promise , selfResolutionError ).
Si Tipo (resolución) no es Objeto, entonces
una. Devuelve FulfillPromise ( promesa , resolución ).
Sea entonces Get( resolución , "entonces" ).
Si entonces es una finalización abrupta, entonces
una. Devuelve RejectPromise( promise , luego .[[Valor]]).
Sea entoncesAcción entonces .[[Valor]].
Si IsCallable( thenAction ) es falso , entonces
una. Devuelve FulfillPromise ( promesa , resolución ).
Deje que thenJobCallback sea HostMakeJobCallback( thenAction ).
Deje que el trabajo sea NewPromiseResolveThenableJob ( promesa , resolución , luego JobCallback ).
Ejecute HostEnqueuePromiseJob( trabajo .[[Trabajo]], trabajo .[[Reino]]).
Devolver indefinido .
No puedo precisar dónde se trata el caso que tiene un objeto como argumento sin una propiedad then .
El paso 9 obtiene la propiedad then
- Sea entonces Get( resolución , "entonces" ).
Hay principalmente cuatro resultados posibles:
then no es una propiedad del objeto, entonces (la variable) representa un registro de finalización con [[Valor]] undefinedthen es una propiedad del objeto, pero evaluarlo produce una excepción (por ejemplo, es un captador y el captador se encuentra con una excepción). entonces es entonces una llamada terminación abrupta .then es una propiedad del objeto, pero no es una funciónthen es una propiedad del objeto, y es una función.El paso 10 busca uno de estos resultados:
- Si entonces es una finalización abrupta, entonces
una. Devuelve RejectPromise( promise , luego .[[Valor]]).
Aquí hay un fragmento que hace que 10.a suceda:
let obj = { get then() { throw "sorry"; } }; new Promise(resolve => resolve(obj)) .catch((err) => console.log("rejected with ", err)) Esto representa el caso en el que then no necesariamente tiene la intención de evaluar como una función (es un captador, por lo que el código debe ejecutarse para determinar eso), pero acceder a él hace que sea imposible saber si sería una función o no, ya que produce una excepción. La especificación menciona la ejecución del getter en [[Get]]
El paso 11 es una simple asignación del campo [[Value]] del registro de finalización recuperado (tenga en cuenta que también hay otros campos, como [[Type]] )
- Sea entoncesAcción entonces .[[Valor]].
El paso 12 comprueba si este valor es una función:
- Si IsCallable( thenAction ) es falso , entonces
una. Devuelve FulfillPromise ( promesa , resolución ).
Si no es una función, la promesa principal se cumple con ese objeto como valor.
Los pasos restantes se ocupan del caso donde entonces es una función.